﻿#region Using Region

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CALTypeLib;
using System.Collections;
using System.Threading;
using Action = System.Action;
using Exception = System.Exception;

using UnisysMassiveImporter_v2.Entidades.Mensajes;
using UnisysMassiveImporter_v2.Entidades.Configuracion;

#endregion

namespace UnisysMassiveImporter_v2.Negocio.InfoImage
{
    /// <summary>
    /// Clase que permite la interacción con el Ambiente InfoImage
    /// </summary>
    public class IIF_Connection
    {
        #region Recursos Globales

        bool abortProcessing;

        private int TIMEOUT_MILISECS = 25000;
        private int TIMEOUT_MILISECS_PROCESS = 60000;

        public CALClient calClient;
        public CALClientList calClientList;
        public CALClientListItem calClientListItem;
        public CALClientListItems calClientListItems;
        public CALError calError;
        public CALMaster calMaster;
        public CALQueue calQueue;
        public CALQueues calQueues;

        
        //private const long OMDENUMCLIENTLISTADD_RETAIN = 0x0001;
       // private const long OMDDPAGEIMAGEWRITE_INCLUDE_MARKUPS = 0x0001;
        /*
        private const int CALQueueListWorkset = 64;
        private const int CALQueueListWorkstep = 128;
        private const int CALQueueListUserOnly = 512;
        */
        #endregion


        
        #region CALTypeLib Calls

        /// <summary>
        /// Connect to Image Server and/or finish previous detected connections made with the same username and password.
        /// </summary>
        /// <param name="userCode">II Username.</param>
        /// <param name="passCode">II Password.</param>
        /// <param name="domainName">II Domain Server.</param>
        /// <returns>True if the connection was successfuly, false in case of error.</returns>
        public bool CreateIIFClient(string userCode, string passCode, string domainName, ref Configuration appConfig,ref Thread_Config thread)
        {
            const long OMDCLIENTCREATE_APPLYFUNCSEC = 0x0001;
            const int CALQueueListWorkstep = 128;
           
            try
            {

                //myLocalLog.LogThis4Text("Conectando al servidor de imágenes en el dominio [" + domainName + "].", null, Logger.Information_Message, 586, threadName);

                if (calClient == null)
                {
                    calMaster = new CALMaster();
                    calClient = (CALClient)calMaster.CreateClient(userCode.Trim(), a.a(passCode.Trim()), domainName.Trim(), OMDCLIENTCREATE_APPLYFUNCSEC);
                    calClientList = (CALClientList)calClient.ClientList;
                }
                else
                {
                    //GTM 30/08/2011
                    //change the invoking method to control abort pending status
                    DestroyIIFClient();
                    calClient = (CALClient)calMaster.CreateClient(userCode, passCode, domainName, OMDCLIENTCREATE_APPLYFUNCSEC);
                    calClientList = (CALClientList)calClient.ClientList;
                    calQueues = (CALQueues)calClient.Queues[CALQueueListWorkstep];
                }
                //  myLocalLog.LogThis4Text("Conección InfoImage establecida satisfactoriamente a dominio [" + domainName + "].", null, Logger.Information_Message, 587, threadName);

                return true;
            }
            catch (Exception exc)
            {
                CriticalMessage critical = new CriticalMessage();
                critical.sendMessage("Imposible Conectar IIF con dominio [" + domainName + "] y usuario [" + userCode + "] ", exc, CriticalMessage.IIF_Error, 204, thread.Name, false, ref appConfig);
                if (calMaster == null)
                {
                    //myLocalLog.LogThis4Text(exc.Message, new Exception("ERROR [CreateIIFClient] CAL Error"), Logger.IIF_Error, 204, threadName);
                    

                    return false;
                }
                calError = calMaster.LastError;
                //myLocalLog.LogThis4Text(exc.Message, new Exception("ERROR [CreateIIFClient] CAL Error " + _gCalError.Code), Logger.IIF_Error, 205, threadName);

                return false;
            }
        }

        /// <summary>
        /// Force the closure of an active connection to Image Server, discarding changes.
        /// </summary>
        private void DestroyIIFClient()
        {
            //myLocalLog.LogThis4Text("Procediento con el forzamiento de cierre de sesión...", null, Logger.Information_Message, 588, threadName);

            try
            {
                if (calClient != null)
                {
                    //GTM - 30/08/2011
                    //previous verify if the current session is not in abort pending status to avoid duplicity

                    //myLocalLog.LogThis4Text("Verificando si la sesión no se encuentra en estado de espera de abortar para evitar la duplicidad.", null, Logger.Information_Message, 589, threadName);

                    if (!abortProcessing)
                    {
                        DestroyIIFClientExplicit();
                    }
                }
            }
            catch (Exception exc)
            {
                calError = calMaster.LastError;
                //myLocalLog.LogThis4Text(exc.Message, new Exception("ERROR [DestroyIIFClient] CAL Error " + _gCalError.Code), Logger.IIF_Error, 206, threadName);

                
            }
        }

        /// <summary>
        /// Exclicity forces the closure of any active connection to Image Server with the credentials specified.
        /// </summary>
        public void DestroyIIFClientExplicit()
        {
            try
            {
                // myLocalLog.LogThis4Text("Verificando conección con el servidor de imágenes...", null, Logger.Information_Message, 590, threadName);

                if (calClient == null)
                {
                    //myLocalLog.LogThis4Text("No hay conecciones abiertas para el usuario [" + _userName + "] con el dominio. [" + _domain + "].", null, Logger.Information_Message, 591, threadName);
                }
                else
                {
                    //myLocalLog.LogThis4Text("Detectamos una sesión abierta para el usuario [" + _userName + "]; procediendo a cerrarla...", null, Logger.Information_Message, 592, threadName);

                    //GTM 30/08/2011
                    //mark the current session as aborted

                    //myLocalLog.LogThis4Text("Marcando la sesión como abortada...", null, Logger.Information_Message, 593, threadName);

                    abortProcessing = true;

                    //
                    // GTM - 05/08/2011
                    // Method invocation rewritten with thread to control timeout
                    // on IIF server 
                    //
                    var subThread = new Thread(delegate()
                    {
                        try
                        {
                            calClient.Destroy(DestroyConstants.calDestroySaveChanges);
                        }
                        catch (Exception exception)
                        {
                            calError = calMaster.LastError;
                            // myLocalLog.LogThis4Text(exception.Message, new Exception("ERROR [DestroyIIFClientExplicit::calDestroySaveChanges - Inner Thread] CAL Error " + _gCalError.Code), Logger.IIF_Error, 207, threadName);

                            
                        }
                    });
                    subThread.Start();
                    var threadResult = subThread.Join(TIMEOUT_MILISECS);

                    if (threadResult == true)
                    {
                        // myLocalLog.LogThis4Text("Sesión cerrada exitosamente.", null, Logger.Information_Message, 280, threadName);
                    }
                    else
                    {

                        // myLocalLog.LogThis4Text("Una excepción de timeout ha ocurrido, tratando de cerrar la sesión, proceso abortado. Tratando un nuevo intento descartando cambios.", null, Logger.Information_Message, 595, threadName);
                    }




                    //GTM - 01/09/2011
                    //new try to LogOff the user, aborting changes

                    //myLocalLog.LogThis4Text("Nuevo intento de hacer LogOff al usuario, abortando cambios...", null, Logger.Information_Message, 596, threadName);

                    if (!threadResult)
                    {
                        subThread = new Thread(delegate()
                        {
                            try
                            {
                                calClient.Destroy(DestroyConstants.calDestroyAbortChanges);
                            }
                            catch (Exception exception)
                            {
                                /*
                                _gCalError = _gCalMaster.LastError;

                                myLocalLog.LogThis4Text(exception.Message, new Exception("ERROR [DestroyIIFClientExplicit::calDestroyAbortChanges - Inner Thread] CAL Error : " +
                                    _gCalError.Code), Logger.IIF_Error, 208, threadName);
                                */
                                
                            }
                        });
                        subThread.Start();
                        threadResult = subThread.Join(TIMEOUT_MILISECS);

                        if (threadResult == true)
                        {
                            // myLocalLog.LogThis4Text("Sesión cerrada exitosamente.", null, Logger.Success_Message, 280, threadName);
                        }
                        else
                        {

                            // myLocalLog.LogThis4Text("Una excepción de timeout ha ocurrido, tratando de cerrar la sesión, proceso abortado. Tratando un nuevo intento descartando cambios.", null, Logger.Information_Message, 595, threadName);
                        }
                    }
                    //_gCalClient.Destroy(DestroyConstants.calDestroySaveChanges);
                    //Console.WriteLine"Sesión de trabajo cerrada exitosamente.");
                }
            }
            catch (Exception exc)
            {
                calError = calMaster.LastError;
                //myLocalLog.LogThis4Text(exc.Message, new Exception("ERROR [DestroyIIFClientExplicit] CAL Error " + _gCalError.Code), Logger.IIF_Error, 209, threadName);
              
            }
        }

        /// <summary>
        /// Clear user's desktop sending pending items to workflow or to archive.
        /// </summary>
        public void ClearIIFClientDesktop()
        {
            try
            {
                //
                // GTM - 05/08/2011
                // Desktop clear operation implemented with thread to handle timeout
                // on IIF response on certain situations.
                // 
                if (calClient != null)
                {
                    var subThread = new Thread(delegate()
                    {
                        try
                        {
                            //check if current session is not marked as aborted

                            //myLocalLog.LogThis4Text("Verificando si la actual sesión no se encuentra marcada como abortada.", null, Logger.Information_Message, 594, threadName);

                            if (!abortProcessing)
                            {
                                calClientList.Clear(
                                    ClientListClearConstants.calClearSendModWIP);
                            }
                        }
                        catch (Exception exception)
                        {
                            //check if current session is not marked as aborted
                            if (!abortProcessing)
                            {
                                calError = calMaster.LastError;

                                /* myLocalLog.LogThis4Text(exception.Message, new Exception("ERROR [ClearIIFClientDesktop - Inner Thread] CAL Error " +
                                   _gCalError.Code), Logger.IIF_Error, 210, threadName);
                                */
                               
                            }
                        }
                    });
                    subThread.Start();
                    var threadResult = subThread.Join(TIMEOUT_MILISECS);
                    // waiting maximum X seconds

                    // myLocalLog.LogThis4Text("Esperando por un máximo de segundos para normalizar el escritorio.", null, Logger.Information_Message, 598, threadName);

                    if (threadResult == true)
                    {
                        // myLocalLog.LogThis4Text("Escritorio normalizado.", null, Logger.Success_Message, 279, threadName);


                    }
                    else
                    {
                        // myLocalLog.LogThis4Text("Ha ocurrido una excepcion de timeout durante la normalizacion del escritorio. Proceso abortado.", null, Logger.Information_Message, 599, threadName);


                    }
                }
            }
            catch (Exception exc)
            {
                calError = calMaster.LastError;

                // myLocalLog.LogThis4Text(exc.Message, new Exception("ERROR [ClearIIFClientDesktop] CAL Error " + _gCalError.Code), Logger.IIF_Error, 211, threadName);

              
            }
        }

        /// <summary>
        /// Check current status of the desktop of the user.
        /// </summary>
        public void CheckStatusIIFClientDesktop()
        {
            try
            {

                //  myLocalLog.LogThis4Text("Verificando el estado de los documentos en el escritorio...", null, Logger.Information_Message, 600, threadName);
                calClientListItems = calClientList.AllItems;

                foreach (CALClientListItem listItem in calClientListItems)
                {
                    CALWorkitemInfo wii = listItem.Info;
                    if (wii.Status == ObjStatusConstants.calObjStatusWIP)
                    {
                        //myLocalLog.LogThis4Text("Enviando objeto WIP a workflow.", null, Logger.Information_Message, 601, threadName);
                        listItem.SendToDefault(SendConstants.calSendDiscard);
                    }
                }
            }
            catch (Exception exc)
            {
                calError = calMaster.LastError;

                // myLocalLog.LogThis4Text(exc.Message, new Exception("ERROR [CheckStatusIIFClientDesktop] CAL Error " + _gCalError.Code), Logger.IIF_Error, 212, threadName);

               
            }
        }

        #endregion CALTypeLib Calls

    }


}
